[译]JavaScript中的剩余参数和默认参数
原文:http://blog.mozilla.org/jorendorff/2012/05/29/rest-arguments-and-default-arguments-in-javascript/
在过去的两周,Benjamin Peterson在SpiderMonkey中实现了两个ES6新特性.如果你经常写JS的话,一定会喜欢这两个特性.
剩余参数(Rest arguments)是我们熟悉的arguments对象的很好的替代品
.语法如下:
function f(arg1, arg2, ...rest) { alert("你传入了" + rest.length + "个额外的参数."); }
这非常类似于Python, Lisp, 以及Ruby中的剩余参数.在每次调用函数f的时候
,前几个形参都会按照顺序被赋上对应的实参值,在这个例子中就是arg1和
arg2
.其他多出来的实参就会存储在数组rest中
.如果没有传入多余的实参,rest就是一个空数组
.
和arguments对象不同的是
,一个剩余参数是一个真实的数组,也就是说可以使用所有的数组方法,包括.shift()
, .forEach()
, .map()等
.还有一个很重要的差别是,arguments对象在每一级的嵌套函数中都会被重新定义,不管你需要不需要,而剩余参数不会,就和普通变量一样,可以在闭包中通过作用域链访问到上层函数的剩余参数.
默认参数(Default arguments)是这样的:
function fade(element, seconds=0.5, targetOpacity=0) { $(element).animate({opacity: targetOpacity}, seconds * 1000); }
当你调用这个函数的时候,如果你没有给某个拥有默认值的形参传值,则这些形参会自动被赋上默认值.
fade(form, 0.2, 1); // 没有使用默认值: // 快速淡入 fade(form, 3); // targetOpacity设置为默认值0: // 缓慢淡出 fade(form); // seconds设置为默认值0.5, // targetOpacity设置为默认值0: // 正常速度淡出
默认值可以是任意的表达式,甚至还可以使用到前面的形参,比如:
function logEvent(event, logger=findLoggerFor(event.target)) { ... }
logger的默认值依赖于
event参数
.
(默认参数的一些技术细节:和Python不同的是,在函数每次被调用时,这个默认参数的值都会被重新计算,也就是说,如果一个参数的默认值被设置为=[]的话
,该参数的值每次都会是一个新的数组.另外一个需要注意的是,目前的提案规定如下,仅在调用者省略一个实参的情况下,对应的形参才会取默认值.如果调用者显式的传一个undefined值给形参
,则该形参的值就是undefined,而不会去取默认值
.不过现在TC39正在讨论,看要不要改成,即使在调用者显式传入undefined的情况下也让形参取默认值
.虽然其他语言没有这么干的,但在用JavaScript操作DOM的使用中,很多情况下都适合这么干.现在SpiderMonkey是依据当前的提案来实现的,一旦提案有改变,我们会更新我们的实现.)
译者注:读者也许不理解和python比较的这几句话,如果你想知道的话:
在python中,拥有默认参数值的参数有时并不像是在JavaScript中的局部变量一样每次都重新求值.看个例子:
>>> def spam(eggs=[]): ... eggs.append("spam") ... return eggs ... >>> spam() ['spam'] >>> spam() ['spam', 'spam'] >>> spam() ['spam', 'spam', 'spam'] >>> spam() ['spam', 'spam', 'spam', 'spam']
这两个新特性都有望成为ES6标准的一部分.Benjamin依然干劲十足,他会给我们带来更多新东西.
译者注:Benjamin Peterson是一个今年刚刚进入Mozilla的实习生,他的另一项壮举是删除了由Brendan Eich最初编写,在SpiderMonkey中用了17年的反编译器.